<?php
/**
* @author		Arunoda Susiripala
* @package		jconnect
* @copyright	Arunoda Susiripala
* @license 		http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
*/

include('xmlrpc/xmlrpc.inc.php');
include('xmlrpc/xmlrpcs.inc.php');
include('init.php');


$methods=array(
			"jc.createUser"=>array(
				'function' => 'createUser',
				'signature' => array(array($xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcString)),
				'docstring'=>'create a new user'
			),
			"jc.updateUser"=>array(
				'function' => 'updateUser',
				'signature' => array(array($xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcString)),
				'docstring'=>'update a existing user'
			),
			"jc.deleteUser"=>array(
				'function' => 'deleteUser',
				'signature' => array(array($xmlrpcString,$xmlrpcString,$xmlrpcString)),
				'docstring'=>'delete the given user'
			),
			"jc.getUserDetails"=>array(
				'function' => 'getUserDetails',
				'signature' => array(array($xmlrpcString,$xmlrpcString,$xmlrpcInt,$xmlrpcInt)),
				'docstring'=>'return the usernames by the chunk size and chunk number'
			),
			"jc.getUsers"=>array(
				'function' => 'getUsers',
				'signature' => array(array($xmlrpcString,$xmlrpcString,$xmlrpcArray)),
				'docstring'=>'return users as array given in the user array\n' .
							'\nif userarray is null return all users.. '
			),
			"jc.login"=>array(
				'function' => 'login',
				'signature' => array(array($xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcBoolean)),
				'docstring'=>'login by provided userr details'
			),
			"jc.logout"=>array(
				'function' => 'logout',
				'signature' => array(array($xmlrpcString,$xmlrpcString,$xmlrpcString)),
				'docstring'=>'logout given user'
			),
			"jc.bulkSync"=>array(
				'function' => 'bulkSync',
				'signature' => array(array($xmlrpcString,$xmlrpcString,$xmlrpcArray)),
				'docstring'=>'synchrize users in bulk'
			),
			"jc.getUserCount"=>array(
				'function' => 'getUserCount',
				'signature' => array(array($xmlrpcString,$xmlrpcString)),
				'docstring'=>'get the # of users'
			),
			"jc.getPublicView"=>array(
				'function' => 'getPublicView',
				'signature' => array(array($xmlrpcString,$xmlrpcString)),
				'docstring'=>'get the html data for activity module(public)'
			),
			"jc.getPrivateView"=>array(
				'function' => 'getPrivateView',
				'signature' => array(array($xmlrpcString,$xmlrpcString,$xmlrpcString)),
				'docstring'=>'get the html data for activity module(private)'
			),
			"jc.loadSysInfo"=>array(
				'function' => 'loadSysInfo',
				'signature' => array(array($xmlrpcString,$xmlrpcString,$xmlrpcStruct)),
				'docstring'=>'send jconenct system info to the exApp'
			)
		);

$xmlrpcServer = new xmlrpc_server($methods, false);

$xmlrpcServer->functions_parameters_type = 'phpvals';

$xmlrpcServer->service();



function createUser($secKey,$username,$email,$password){
	if(!checkValidity($secKey)){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(125,"Secret key invalid!")));
	}
	else if(!$username || !$password || !$email){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(126,"all parameters should be have a value")));
	}
	else{
		try{
			$user=new User();
			$user->username=$username;
			$user->password=$password;
			$user->email=$email;
			
			$user->save();	
		}
		catch(Exception $ex){
			if(preg_match("/<1062>/", $ex->getMessage())){
				return new xmlrpcresp(php_xmlrpc_encode(
					new Fault(128,"username confilicts")));
			}else{
				return new xmlrpcresp(php_xmlrpc_encode(
					new Fault(127,$ex->getMessage())));
			}
		}
		
		return new xmlrpcresp(php_xmlrpc_encode(
			true));
	}	
}

function updateUser($secKey,$username,$email,$password){
	if(!checkValidity($secKey)){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(125,"Secret key invalid!")));
	}
	else if(!$username){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(126,"username should be valid")));
	}
	else{
		try{
			$user=new User($username);
			if($password) $user->password=$password;
			if($email) $user->email=$email;	
			$user->save();	
		}
		catch(Exception $ex){
			return new xmlrpcresp(php_xmlrpc_encode(
				new Fault(127,$ex->getMessage())));
		}
		
		return new xmlrpcresp(php_xmlrpc_encode(
			true));
	}	
}

function deleteUser($secKey,$username){
	if(!checkValidity($secKey)){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(125,"Secret key invalid!")));
	}
	else if(!$username){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(126,"username should be valid")));
	}
	else{
		try{
			$user=new User($username);
			$user->delete();	
		}
		catch(Exception $ex){
			return new xmlrpcresp(php_xmlrpc_encode(
				new Fault(127,$ex->getMessage())));
		}
		

		
		return new xmlrpcresp(php_xmlrpc_encode(
			true));
	}	
}

/** (this is used for user-sync)
	Here usernames are return by the block of usernames size  by @see $chunksize and
	the $chunkNo th block
	eg:- if we have 1500 users @see $chunksize 500, $chunkNo 2 will send user from 501-1000..
 */
function getUserDetails($secKey,$chunkSize,$chunkNo){
	if(!checkValidity($secKey)){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(125,"Secret key invalid!")));
	}
	else{
		try{
			new User(); // to get the database access..
			
			$sql="SELECT username,email FROM users ORDER BY id ASC LIMIT ".
			(($chunkNo-1)*$chunkSize) ."," .($chunkSize);

			if(!($result=mysql_query($sql))) throw new Exception(mysql_error());
			
			$users=array();
			$lc=0;
			while(($row=mysql_fetch_row($result))){
				$users[$lc++]=$row;
			}
		
			return $users;

		}
		catch(Exception $ex){
			return new xmlrpcresp(php_xmlrpc_encode(
				new Fault(127,$ex->getMessage())));
		}
	}	
}
/**
 * 	@param $secKey secretKey
 * 	@param $usernameList array of usernames
	@return array of users. format => array(array("kamal","kamal@yahoo.com"),...);
 */
function getUsers($secKey,$usernameList){
	if(!checkValidity($secKey)){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(125,"Secret key invalid!")));
	}
		
	try{
		$userList=array();
		for($lc=0;$lc<count($usernameList);$lc++){
			$user=new User($usernameList[$lc]);
			$userList[$lc]=array($user->username,$user->email);
		}
		
		return new xmlrpcresp(php_xmlrpc_encode(
		      $userList));
	}
	catch(Exception $ex){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(127,$ex->getMessage())));
	}
}

function login($secKey,$username,$password,$remember){
	if(!checkValidity($secKey)){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(125,"Secret key invalid!")));
	}
	else if(!$username){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(126,"username should be valid")));
	}
	else{
		try{
			$user=new User($username);
			$logined=false;
			if($user->password==$password){
				$logined=true;
			}
			
			return new xmlrpcresp(php_xmlrpc_encode(
				$logined));
		}
		catch(Exception $ex){
			return new xmlrpcresp(php_xmlrpc_encode(
				new Fault(127,$ex->getMessage())));
		}
	}
}

function logout($secKey,$username){
	if(!checkValidity($secKey)){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(125,"Secret key invalid!")));
	}
	else if(!$username){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(126,"username should be valid")));
	}
	else{
		try{
			$user=new User($username);

			return new xmlrpcresp(php_xmlrpc_encode(
				true));
		}
		catch(Exception $ex){
			return new xmlrpcresp(php_xmlrpc_encode(
				new Fault(127,$ex->getMessage())));
		}
	}
}

/**
 * The returning html data will be displayed for public view
 * return data is in a intArray in ascii values because xmlrpc doesn't allow "<>&".. chars
 * use above strToIntArray like function
	@return - html data(public) in a intArray
 */
function getPublicView($secKey){
	if(!checkValidity($secKey)){
		return new xmlrpcresp(php_xmlrpc_encode(
		new Fault(125,"Secret key invalid!")));
	}


	try{
		$html="This is the Public View Loaded from FakeApp <br>".
		"<img src='http://tbn0.google.com/images?q=tbn:imjQzCDCyJyz-M:http://www.uncoached.com/wp-content/uploads/2009/01/google_logo_5.jpg'/> <br> I Love Google..";

		return new xmlrpcresp(php_xmlrpc_encode(
		strToIntArray($html)));
	}
	catch(Exception $ex){
		return new xmlrpcresp(php_xmlrpc_encode(
		new Fault(127,$ex->getMessage())));
	}

}

function strToIntArray($string){
	$intArray=array();
	for($lc=0;$lc<strlen($string);$lc++){
		array_push($intArray,ord(substr($string,$lc,1)));
	}
	return $intArray;
}

/**
 * The returning html data will be displayed when particular user-logged in..
 * return data is in a intArray in ascii values because xmlrpc doesn't allow "<>&".. chars
 * use above strToIntArray like function
	@return - html data(private) in a intArray
 */
function getPrivateView($secKey,$username){
	if(!checkValidity($secKey)){
		return new xmlrpcresp(php_xmlrpc_encode(
		new Fault(125,"Secret key invalid!")));
	}
	else if(!$username){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(126,"username should be valid")));
	}

	try{
		$user=new User($username);
		$html="This is the Private View Loaded from FakeApp for user $username ".
			"<b> email $user->email <b>".
			"<br>Joomla Rox <br>".
			"<img src='http://community.joomla.org/templates/joomla08sand/images/logo.png' width=150/>";
		return new xmlrpcresp(php_xmlrpc_encode(
			strToIntArray($html)));
	}
	catch(Exception $ex){
		return new xmlrpcresp(php_xmlrpc_encode(
		new Fault(127,$ex->getMessage())));
	}

}

/**
 this is called when bulk user -sync is there...
$userList is a array containing user-objects with username and email

And this function should not trigger back to Joomla for username changes

this function return the array of error messages containing user and the message
 * 	@param $secKey secretKey
 * 	@param $userList array of format => array(array("kamal","kamal@yahoo.com"),...);
	@return array of errors. format => array(array("kamal","error message"),...);
 */
function bulkSync($secKey,$userList){
	if(!checkValidity($secKey)){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(125,"Secret key invalid!")));
	}
	
	$exceptions=array();
	foreach($userList as $id=>$user){
		try{
			$usr=new User();
			$usr->username=$user[0];
			$usr->email=$user[1];
			$usr->password=substr(md5(rand()),0,25);
			$usr->save();
		}
		catch(Exception $ex){
			$size=sizeof($exceptions);
			$exceptions[$size][0]=$user[0];
			$exceptions[$size][1]=$ex->getMessage();
		}
	}

	return new xmlrpcresp(php_xmlrpc_encode(
			$exceptions));
	
}
/**
 * 
 * Returns the # of users in ExApp
 * @return user count
 */
function getUserCount($secKey){
	if(!checkValidity($secKey)){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(125,"Secret key invalid!")));
	}
	
	try{
		new User();
		$sql= "SELECT COUNT(*) FROM users";
		if(!($result=mysql_query($sql))) throw new Exception(mysql_error());
		$row=mysql_fetch_row($result);
		return new xmlrpcresp(php_xmlrpc_encode(
			(int)$row[0]));
	}catch(Exception $ex){
			return new xmlrpcresp(php_xmlrpc_encode(
				new Fault(127,$ex->getMessage())));
	}
	
	
}

/**
	This is the function probabaly called by the JConnect to inform exApp about jconnect details...
	like host,port,path it's xmlrpc server stayes..
	
	@param $secKey -security key
	@parama $meta - array containing jconnect info...
				possible keys are..
				JC_PATH,JC_HOST,JC_PORT,APPNAME
 */
function loadSysInfo($secKey,$meta){
	if(!checkValidity($secKey)){
		return new xmlrpcresp(php_xmlrpc_encode(
			new Fault(125,"Secret key invalid!")));
	}
	
	try{
		$params="";
		if(isset($meta['PARAMS'])){
			foreach($meta['PARAMS'] as $name=>$value){
				$params.="$name=$value&";
			}
			$params=substr($params,0,strlen($params)-1);
		}
		
		if(isset($meta['JC_PATH'])) setMeta('joomla_path',$meta['JC_PATH']."?$params");
		if(isset($meta['JC_HOST'])) setMeta('joomla_host',$meta['JC_HOST']);
		if(isset($meta['JC_PORT'])) setMeta('joomla_port',$meta['JC_PORT']);
		if(isset($meta['APPNAME'])) setMeta('appName',$meta['APPNAME']);
		
	}catch(Exception $ex){
			return new xmlrpcresp(php_xmlrpc_encode(
				new Fault(127,$ex->getMessage())));
	}
}